import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
import numpy as np

digits = load_digits()
def plot_the_digist():
    # plot the digits
    fig = plt.figure(figsize=(6, 6))  # figure size in inches
    fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)
    # plot the digits: each image is 8x8 pixels
    for i in range(64):
        ax = fig.add_subplot(8, 8, i + 1, xticks=[], yticks=[])
        ax.imshow(digits.images[i], cmap=plt.cm.binary)
        # label the image with the target value
        ax.text(0, 7, str(digits.target[i]))
    plt.show()
    print (len(digits.data[0]))


def sigmoid(inX):
    result = 1.0/(1+np.exp(-inX))
    return result

class Logistic(object):

    def __init__(self, data, lable):
        self.data = data
        self.lable = lable
        self.data_num, n = np.shape(data)
        self.weights = np.ones(n)
        self.possibility = []

    def train(self, iteration):

        '''
        Args:
            data (np.ndarray): 训练数据集
            lable (np.ndarray): 训练标签
            iteration (int): 训练轮数
        '''
        for i in range(iteration):
            for j in range(self.data_num):

                alpha = 0.01
                error = self.lable[j] - sigmoid(sum(self.data[j] * self.weights))
                self.weights += alpha * error * self.data[j]

        return self.weights

def Muticlassification(testData, weight):
    num = np.shape(testData)[0]
    result = np.zeros(num)
    possibility = np.zeros(num)
    for i in range(num):    #对每一个数字进行分类
        mutiPossibilities = np.zeros(10)
        for j in range(10): #每一个数字要在十个分类器里都过一遍
            mutiPossibilities[j] = sigmoid(sum(testData[i] * weight[j]))
        result[i] = np.argmax(mutiPossibilities)    #概率最大的index
        possibility[i] = np.max(mutiPossibilities)  #最大的概率
    
    return np.array(result), np.array(possibility)
        


if __name__ == '__main__':
    #plot_the_digist()
    train_data = digits.data[0: 1000]   #1000个训练集
    test_data = digits.data[1200:1500]  #300个测试集
    test_lable = digits.target[1200:1500]
    weight = np.ones((10, 64))  #10个数，每一个数字对应了64个输入，每一个输入有一个权重
    accurate = 0.0
    for i in range(10):
        target_lable = digits.target[0: 1000] 
        train_lable = []
        for j in range(1000):
            if target_lable[j] == i:
                train_lable.append(1)
            else:
                train_lable.append(0)
        logistic = Logistic(train_data, train_lable)
        weight[i] = logistic.train(500)
        print(" "+str(i)+" 训练完成")
    result, possibility = Muticlassification(test_data, weight)
    for i in range(299):
        print("预测值为："+str(result[i])+" 可能性为："+str(round(possibility[i],2))+" 真实值为："+str(test_lable[i]))
        if test_lable[i] == result[i]:
            accurate += 1

    print("正确率为: "+str(accurate/300))


        
        

